package org.mipt.infsec.steganography.gui;

import org.mipt.infsec.steganography.action.*;
import org.mipt.infsec.steganography.components.ImagePanel;
import org.mipt.infsec.steganography.impl.petzib.DecryptorImpl;
import org.mipt.infsec.steganography.impl.petzib.EncryptorImpl;
import org.mipt.infsec.steganography.parameters.Parameters;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;

public class GuiFrame extends JFrame {
	private JTextField input = new JTextField("Input key or data");
	public GuiFrame() {
        input = new JTextField();
		setSize(Parameters.GUIFRAME_WIDTH, Parameters.GUIFRAME_HEIGHT);
		Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize();
		setLocation(scrSize.width/2 - Parameters.GUIFRAME_WIDTH/2, scrSize.height/2 - Parameters.GUIFRAME_HEIGHT/2);
		setTitle(Parameters.PROGRAM_NAME);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		addWindowListener(new WindowEventsHandler());
        JFrame jfr = new JFrame();
        Container container = jfr.getContentPane();
        container.add(input);
        input.setActionCommand("Start");
		createComponents();
	}
	
	public void openImage() {
		if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
			loadImageFile(fileChooser.getSelectedFile());
		}
	}
    private JFileChooser fileChooser;

	public void encryptImage() throws IOException {
        InputStream inImage = null;
        try {
            inImage = new FileInputStream(fileChooser.getSelectedFile());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        String data = JOptionPane.showInputDialog(this, "Input text", Parameters.PROGRAM_NAME, JOptionPane.INFORMATION_MESSAGE);

		
		if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
			try {
                File outImage = ImageFilter.addExtension(fileChooser.getSelectedFile());
                EncryptorImpl encryptor = new EncryptorImpl(inImage, data);
                encryptor.setOutFile(outImage);
                encryptor.encrypt();

                String key = (String)encryptor.encrypt();
                if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
                imagePanel.setString("<html><p>Key: <Br>\n" +
                        "   <textarea name=\"comment\" cols=\"40\" rows=\"3\">"+key + "</textarea></p></html>");
               // System.out.println("Key: " + key);
               }
				imagePanel.loadImage(outImage);
				Parameters.showInformationMessage(this, Parameters.MESSAGE_ENCRYPTION_COMPLETED);
			} catch (IOException e) {
				Parameters.showErrorMessage(this, Parameters.MESSAGE_IO_ERROR, e.getMessage());
			} catch (NullPointerException e) {
				Parameters.showErrorMessage(this, Parameters.MESSAGE_UNEXPECTED_ERROR, e.getMessage());
			}
        }

	}
	
	public void decryptImage() {
		try {
            Box rowTwo = Box.createHorizontalBox();
            rowTwo.add(new JPasswordField());
            JFrame k = new JFrame("Input key");
            Container content = k.getContentPane();
            content.add(rowTwo, BorderLayout.SOUTH);
            String key = JOptionPane.showInputDialog(this, "Input key", Parameters.PROGRAM_NAME, JOptionPane.INFORMATION_MESSAGE);
            DecryptorImpl decryptor = new DecryptorImpl(fileChooser.getSelectedFile(), key);
            String result = (String)decryptor.decrypt();
            System.out.println(result);
            imagePanel.setString("<html><p>Data: <Br>\n" +
                        "   <textarea rows=\"2\" cols=\"20\" >"+ result + "</textarea></p></html>");
			} catch (IOException e) {
			Parameters.showErrorMessage(this, Parameters.MESSAGE_IO_ERROR, e.getMessage());
		} catch (NullPointerException e) {
			Parameters.showErrorMessage(this, Parameters.MESSAGE_UNEXPECTED_ERROR, e.getMessage());
		}
	}
	
	public void exit() {
		this.dispose();
	}
	
	private ImagePanel imagePanel;

	
	private void createComponents() {
		JMenu fileMenu = new JMenu("File");
		fileMenu.add(new OpenAction(this));
		fileMenu.addSeparator();
		fileMenu.add(new ExitAction(this));
		
		JMenu encryptionMenu = new JMenu("Encryption");
		encryptionMenu.add(new ImageEncryptorAction(this));
		
		JMenu decryptionMenu = new JMenu("Decryption");
		decryptionMenu.add(new ImageDecryptionAction(this));
		
		JMenu helpMenu = new JMenu("Help");
		helpMenu.add(new AboutAction(this));
		
		JMenuBar menuBar = new JMenuBar();
		menuBar.add(fileMenu);
		menuBar.add(encryptionMenu);
		menuBar.add(decryptionMenu);
		menuBar.add(helpMenu);
		setJMenuBar(menuBar);
		
		fileChooser = new JFileChooser();
		fileChooser.setCurrentDirectory(new File("."));
		fileChooser.setAcceptAllFileFilterUsed(false);
		fileChooser.setMultiSelectionEnabled(false);
        fileChooser.addChoosableFileFilter(new ImageFilter());
        fileChooser.setAccessory(new ImagePreview(fileChooser));
		
		imagePanel = new ImagePanel();
		
		this.add(imagePanel, BorderLayout.CENTER);
		
	}
	
	private void loadImageFile(File f) {
		try {
			imagePanel.loadImage(f);
		} catch (IOException e) {
			Parameters.showErrorMessage(this, Parameters.MESSAGE_IO_ERROR, e.getMessage());
		} catch (Exception e) {
			Parameters.showErrorMessage(this, Parameters.MESSAGE_UNEXPECTED_ERROR, e.getMessage());
		}
		
	}


    private class WindowEventsHandler extends WindowAdapter {
		@Override
		public void windowClosing(WindowEvent e) {
			GuiFrame.this.exit();
		}
	}
	
	
}
